home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / Symmetry & Tiles / Tiler Code / Group2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-27  |  5.8 KB  |  214 lines  |  [TEXT/KAHL]

  1. #include     <graphics libraries.h>
  2. #include     <graphics toolbox.h>
  3. #include     "SymmetryUtils.h"
  4. #include    "TileConstants.h"
  5. #include    "TileProtos.h"
  6. #include     "Group2.h"
  7.  
  8. extern gxPatternRecord    gPattern;
  9. extern gxShape            gTileShape;
  10. extern dragger            gDragger;        // A record containing a manipulable contour & associated stuff
  11. extern gxShape            gOpShapes[];    // Group of shapes to show the
  12.                                         // symmetry operations
  13. extern gxViewPort        gViewPort;
  14.  
  15. extern Boolean            gContRedraw, gKeepClosed;
  16.  
  17. // Prototype of a function in utils.c we use
  18. long     labs(long i);
  19.  
  20.  
  21. ///////////////////////////////////////////////////////////////////////////////////
  22. //    Group p2
  23.  
  24. // Test for a hit on an op shape, tracking the drag and returning true
  25. // if one was hit, false otherwise
  26. Boolean    p2_OpShapeHit(gxPoint *clickPt)
  27. {
  28.     gxHitTestInfo    hitStats;
  29.     gxShape            hitShape, oldShape;
  30.     gxTransform        xForm;
  31.     long            shapeNum;
  32.     
  33.     // Don't check shpe 0
  34.     for(shapeNum = 1; shapeNum < 3; shapeNum++)
  35.     {
  36.         hitShape = gOpShapes[shapeNum];
  37.         xForm = GXGetShapeTransform(hitShape);
  38.         
  39.         // Test for a hit on the startCap
  40.         GXIgnoreGraphicsNotice(attributes_already_set);
  41.         GXSetTransformHitTest(xForm, gxAnyPart, kHitTolerance);
  42.         GXPopGraphicsNotice();
  43.             
  44.         // If shape was hit, we're done looking
  45.         if(GXHitTestShape(hitShape, clickPt, &hitStats))
  46.             break;
  47.     }
  48.     
  49.     // If a shape was hit, track it
  50.     if(shapeNum < 3)
  51.     {
  52.         gxPoint        anchor, pt, lastPt = *clickPt;
  53.         
  54.         hitShape = gOpShapes[shapeNum];
  55.         
  56.         // Get the "anchor" point (shape 0)
  57.         GXGetPoint(gOpShapes[0], &anchor);
  58.         
  59.         // Create a shape for saving the old position
  60.         if(!gContRedraw)
  61.             oldShape = GXCopyToShape(nil, hitShape);
  62.  
  63.         // Follow the drag around
  64.         while(StillDown())
  65.         {
  66.             // Get the new mouse position and if it's different,
  67.             // adjust the dragged shape
  68.             GXGetViewPortMouse(gViewPort, &pt);
  69.             if(pt.x != lastPt.x || pt.y != lastPt.y)
  70.             {
  71.                 // Save old shape so we can erase and draw in rapid succession
  72.                 if(!gContRedraw)
  73.                 {
  74.                     GXCopyToShape(oldShape, hitShape);
  75.                     
  76.                     // If constraints are on, erase the dragger before.
  77.                     if(gKeepClosed)
  78.                         EraseAShape(gDragger.snake1);
  79.                 }
  80.                 
  81.                 // Move it
  82.                 p2_DragOpShape(hitShape, &pt, &anchor);
  83.                 
  84.                 if(gContRedraw)
  85.                 {
  86.                     // Reset pattern and draw it right now
  87.                     p2_ChangeLattice();
  88.                       OffToScreen();
  89.                 }
  90.                   else
  91.                   {
  92.                     // Erase and draw
  93.                     EraseAShape(oldShape);
  94.                     GXDrawShape(hitShape);
  95.                     
  96.                     // If constraints are on, draw the dragger too.
  97.                     if(gKeepClosed)
  98.                         GXDrawShape(gDragger.snake1);
  99.                   }
  100.               }
  101.             lastPt = pt;
  102.         }
  103.         if(!gContRedraw)
  104.         {
  105.             p2_ChangeLattice(); // Update the pattern
  106.             GXDisposeShape(oldShape);
  107.         }
  108.         return true;
  109.     }
  110.     else    // nothing hit
  111.         return false;
  112. }
  113.  
  114. // Moves the op shape as appropriate
  115. void    p2_DragOpShape(gxShape dragShape, gxPoint *clickPt, gxPoint *anchor)
  116. {
  117.     fixed    xd = clickPt->x - anchor->x, yd = clickPt->y - anchor->y,
  118.             lxd = labs(clickPt->x - anchor->x), lyd = labs(clickPt->y - anchor->y);
  119.     gxPoint    temp;
  120.     
  121.     // If the point is in bounds, just use it
  122.     if(lxd < kMaxDistance && lyd < kMaxDistance &&
  123.         (lyd > kMinDistance || lxd > kMinDistance) )
  124.     {
  125.         GXSetPoint(dragShape, clickPt);
  126.     }
  127.     else  // Constrain it to the bounds
  128.     {
  129.         temp = *clickPt;
  130.         if( lxd > kMaxDistance )
  131.             temp.x = anchor->x + ( (xd < 0) ? -kMaxDistance : kMaxDistance);
  132.         else if( lxd < kMinDistance )
  133.             temp.x = anchor->x + ( (xd < 0) ? -kMinDistance : kMinDistance);
  134.         
  135.         if( lyd > kMaxDistance )
  136.             temp.y = anchor->y + ( (yd < 0) ? -kMaxDistance : kMaxDistance);
  137.         else if( lyd < kMinDistance )
  138.             temp.y = anchor->y + ( (yd < 0) ? -kMinDistance : kMinDistance);
  139.         
  140.         GXSetPoint(dragShape, &temp);
  141.     }
  142. }
  143.  
  144. // Called either to set the default shapes when resetting the tile, or when 
  145. // the symmetry has changed, to convert one lattice type to another.
  146. // Currently only resets to default
  147. void     p2_RemakeOpShapes(Boolean useDefaults)
  148. {
  149.     gxShape    tempShape;
  150.     
  151.     if(true /* useDefaults */)
  152.     {
  153.         tempShape = MakeOpShape(roto2Op);
  154.         GXMoveShape(tempShape, kStartingOffset, kStartingOffset);
  155.         gOpShapes[0] = GXCopyToShape(nil, tempShape);
  156.         GXMoveShape(tempShape, kStartingGridSize, 0);
  157.         gOpShapes[1] = GXCopyToShape(nil, tempShape);
  158.         GXMoveShape(tempShape, -kStartingGridSize, kStartingGridSize);
  159.         gOpShapes[2] = tempShape;
  160.     }
  161. }
  162.  
  163. // Set the dragger to the default shape.
  164. void    p2_SetDefaultDragger(gxShape snake)
  165. {
  166.     long        dragPoly[] = {    1,    // number of contours
  167.                                 4,    // number of points
  168.                                 0, kStartingGridSize,
  169.                                 0, 0,
  170.                                 kStartingGridSize, 0,
  171.                                 kStartingGridSize, kStartingGridSize  };
  172.                 
  173.  
  174.     // make the starting drag shape
  175.     GXSetPolygons(snake, (gxPolygons *) dragPoly);
  176.     GXMoveShape(snake, kStartingOffset, kStartingOffset);
  177. }
  178.  
  179. // Reset the pattern vectors according to the positions of the op shapes
  180. void    p2_ChangeLattice(void)
  181. {
  182.     gxPoint        start, end1, end2;
  183.  
  184.     // Adjust points to define the true unit cell.
  185.     GXGetPoint(gOpShapes[0], &start);
  186.     GXGetPoint(gOpShapes[1], &end1);
  187.     GXGetPoint(gOpShapes[2], &end2);
  188.     gPattern.u.x = 2 *(end1.x - start.x);
  189.     gPattern.u.y = 2 * (end1.y - start.y);
  190.     gPattern.v.x = 2 * (end2.x - start.x);
  191.     gPattern.v.y = 2 * (end2.y - start.y);
  192.     
  193.     // Now remake the pattern according to the new lattice and draw it offscreen
  194.     RemakeTile();
  195. }
  196.  
  197. // Repeat the tile geometry as necessary to build up the full unit cell
  198. void    p2_BuildCellShape(gxShape snake)
  199. {
  200.     gxShape    tempShape;
  201.     gxPoint    origin, ctr;
  202.     
  203.     // Get the point to rotate around: center of the unit cell
  204.     GXGetPoint(gOpShapes[0], &origin);
  205.     ctr.x = origin.x + (gPattern.u.x + gPattern.v.x) / 2;
  206.     ctr.y = origin.y + (gPattern.u.y + gPattern.v.y) / 2;
  207.     
  208.     // Copy the shape, rotate it, and add it back in
  209.     tempShape = GXCopyToShape(nil, gTileShape);
  210.     GXRotateShape(tempShape, ff(180), ctr.x, ctr.y);
  211.     GXSetShapeParts(gTileShape, 0, gxSelectToEnd, tempShape, gxBreakLeftEdit);
  212.     GXDisposeShape(tempShape);
  213. }
  214.